package com.mlink.ai.chat.ui.activity

import android.animation.AnimatorSet
import android.graphics.Color
import android.graphics.Paint
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.adjust.sdk.Adjust
import com.adjust.sdk.AdjustPlayStoreSubscription
import com.android.billingclient.api.*
import com.android.billingclient.api.BillingClient.ProductType
import com.icekrvams.billing.Billing
import com.icekrvams.billing.BillingFlowDraftCallback
import com.icekrvams.billing.listeners.PurchaseConfirmListener
import com.mlink.ai.chat.AiChatApplication
import com.mlink.ai.chat.assistant.robot.R
import com.mlink.ai.chat.assistant.robot.databinding.ActivityBillingBinding
import com.mlink.ai.chat.constants.PRIVACY_POLICY_URL
import com.mlink.ai.chat.constants.SUB_ID_AICHAT_ONE_WEEK
import com.mlink.ai.chat.constants.SUB_ID_AICHAT_ONE_YEAR
import com.mlink.ai.chat.constants.TERMS_OF_SERVICE_URL
import com.mlink.ai.chat.utils.*
import com.mlink.ai.chat.utils.openUrl
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.DecimalFormat

class BillingActivity : BaseActivity<ActivityBillingBinding>() {

    private lateinit var animatorSet: AnimatorSet

    private var subId = SUB_ID_AICHAT_ONE_WEEK

    private val appViewModel = AiChatApplication.app.appViewModel

    private var productId: String? = null
    private var purchase: Purchase? = null
    private var vipType: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        window.decorView.systemUiVisibility =
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        window.statusBarColor = Color.TRANSPARENT
        vipType = intent.getStringExtra(KEY_VIP_TYPE)
        AnalyticsEvents.SHOW_SUB_PAGE.logEvent()
    }

    override fun getViewBinding(): ActivityBillingBinding {
        return ActivityBillingBinding.inflate(layoutInflater)
    }

    override fun initViews() {

        appViewModel.getSubscribeLiveData().observe(this) {
            if (it) {
                if (!MMKV.defaultMMKV().decodeBool(KEY_SUBSCRIPTION_EVENTS_LOGGED, false)) {
                    var bundle: Bundle? = null
                    vipType?.let {
                        bundle = Bundle().apply {
                            putString(AnalyticsParams.KEY_VIP_TYPE, vipType)
                        }
                    }
                    when (subId) {
                        SUB_ID_AICHAT_ONE_WEEK -> {
                            AnalyticsEvents.FIRST_PURCHASED_WEEKLY_TRY.logEvent(bundle)
                            AnalyticsEvents.FIRST_PURCHASED_ALL_TRY.logEvent(bundle)

                            AnalyticsEvents.FIRST_PURCHASED_WEEKLY_TRY.logFacebookEvent(this, bundle)
                            AnalyticsEvents.FIRST_PURCHASED_ALL_TRY.logFacebookEvent(this, bundle)
                        }

                        SUB_ID_AICHAT_ONE_YEAR -> {
                            AnalyticsEvents.PURCHASED_YEARLY_SUCCESS.logEvent(bundle)
                            AnalyticsEvents.PURCHASED_YEARLY_SUCCESS.logFacebookEvent(this, bundle)
                        }
                    }
                    AnalyticsEvents.FIRST_ALLIAP_SUCCESS.logEvent(bundle)
                    AnalyticsEvents.FIRST_ALLIAP_SUCCESS.logFacebookEvent(this, bundle)
                    MMKV.defaultMMKV().encode(KEY_SUBSCRIPTION_EVENTS_LOGGED, true)
                }
                finish()
            }
        }

        appViewModel.purchaseLiveData.observe(this) {
            productId = it.first
            purchase = it.second

        }

        lifecycleScope.launch {
            // 延迟 5 秒
            delay(5000)

            withContext(Dispatchers.Main) {
                binding.closeIv.visibility = View.VISIBLE
            }
        }

        ColorText(resources.getString(R.string.sub_title))
            .with(
                resources.getString(R.string.unlimited), Color.parseColor("#70FFBE")
            ).build().run {
                binding.subTitle.text = this

            }

        val statusBarHeight = getStatusBarHeight()
        val closeLayoutParams = binding.closeIv.layoutParams as ViewGroup.MarginLayoutParams
        closeLayoutParams.topMargin = 8.dp2px() + statusBarHeight
        binding.closeIv.layoutParams = closeLayoutParams

        val restoreLayoutParams = binding.restoreTv.layoutParams as ViewGroup.MarginLayoutParams
        restoreLayoutParams.topMargin = 8.dp2px() + statusBarHeight
        binding.restoreTv.layoutParams = restoreLayoutParams

        val weekFormattedPrice = Billing.getFormattedPrice(SUB_ID_AICHAT_ONE_WEEK)
        if (weekFormattedPrice != null) {
            binding.subWeekTv.text =
                String.format(getString(R.string.sub_week_price, weekFormattedPrice))
        } else {
            binding.subWeekTv.text = String.format(
                getString(
                    R.string.sub_week_price,
                    getString(R.string.sub_week_default_price)
                )
            )
        }

        val yearFormattedPrice = Billing.getFormattedPrice(SUB_ID_AICHAT_ONE_YEAR)
        if (yearFormattedPrice != null) {
            binding.subYearTv.text =
                String.format(getString(R.string.sub_year_price, yearFormattedPrice))
        } else {
            binding.subYearTv.text = String.format(
                getString(
                    R.string.sub_year_price,
                    getString(R.string.sub_year_default_price)
                )
            )
        }

        val yearPrice = Billing.getPrice(SUB_ID_AICHAT_ONE_YEAR)
        val result = if (yearPrice != null && yearFormattedPrice != null) {
            val decimalFormat = DecimalFormat("#.##")
            val weekPrice = decimalFormat.format(yearPrice / 52)
            val regex = Regex("""[\d,.]+""")
            yearFormattedPrice.replace(regex, weekPrice.toString())

        } else getString(R.string.only_per_week_default_price)


        binding.subOnlyTv.text = String.format(getString(R.string.only_per_week), result)


        binding.closeIv.setOnClickListener {
            finish()
        }

        binding.restoreTv.setOnClickListener {
            if (purchase == null) {
                val queryPurchasesParams =
                    QueryPurchasesParams.newBuilder().setProductType(ProductType.SUBS).build()
                Billing.billingClient.queryPurchasesAsync(
                    queryPurchasesParams
                ) { _, purchasesList ->
                    // 查询已拥有商品信息结果回调。
                    if (purchasesList.isEmpty()) {
                        appViewModel.setSubscribed(false)
                        return@queryPurchasesAsync
                    }
                    val purchase = purchasesList[0]
                    if (purchase.products.firstOrNull()
                            .isNullOrEmpty() || purchase.orderId.isEmpty() ||
                        purchase.purchaseToken.isEmpty()
                    ) {
                        appViewModel.setSubscribed(false)
                        return@queryPurchasesAsync
                    }
                    val pair = Pair<String, Purchase>(purchase.products[0], purchase)
                    appViewModel.purchaseLiveData.value = pair
                    appViewModel.doRestore(
                        purchase.products[0], purchase.orderId, purchase.purchaseToken
                    )
                }
                return@setOnClickListener
            }
            purchase?.run {
                val orderId = orderId
                val purchaseToken = purchaseToken
                if (orderId.isEmpty() || purchaseToken.isEmpty()) return@setOnClickListener
                productId?.let {
                    appViewModel.doRestore(it, orderId, purchaseToken)
                }
            }
        }

        binding.subYearCategory.setOnClickListener {
            binding.subYearCategory.setBackgroundResource(R.drawable.shape_bg_sub_selected)
            binding.subWeekTv.setBackgroundResource(R.drawable.shape_bg_sub_unselected)
            binding.subBtnTry.setText(R.string.sub_continue)
            if (subId == SUB_ID_AICHAT_ONE_YEAR) {
                binding.subBtnTry.performClick()
            }
            subId = SUB_ID_AICHAT_ONE_YEAR
            AnalyticsEvents.CLICK_SUB_YEARLY.logEvent()
        }

        binding.subWeekTv.setOnClickListener {
            binding.subYearCategory.setBackgroundResource(R.drawable.shape_bg_sub_unselected)
            binding.subWeekTv.setBackgroundResource(R.drawable.shape_bg_sub_selected)
            binding.subBtnTry.setText(R.string.sub_tree_free_for_3_days)
            if (subId == SUB_ID_AICHAT_ONE_WEEK) {
                binding.subBtnTry.performClick()
            }
            subId = SUB_ID_AICHAT_ONE_WEEK
            AnalyticsEvents.CLICK_SUB_WEEKLY.logEvent()
        }

        binding.subTryCard.post {
            animatorSet = AnimationUtil.startShakeAndFlashAnimation(this, binding.subTryCard, binding.lightIv)
            animatorSet.start()
        }

        handleBillingPurchase()

        binding.privacyTv.paintFlags = binding.privacyTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
        binding.privacyTv.setOnClickListener {
            openUrl(PRIVACY_POLICY_URL)
        }

        binding.termsTv.paintFlags = binding.termsTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
        binding.termsTv.setOnClickListener {
            openUrl(TERMS_OF_SERVICE_URL)
        }

    }

    private fun handleBillingPurchase() {
        Billing.addPurchaseConfirmListener(object : PurchaseConfirmListener {
            override fun onSubAcknowledged(purchase: Purchase) {
                super.onSubAcknowledged(purchase)

                if (purchase.products.firstOrNull()
                        .isNullOrEmpty() || purchase.orderId.isEmpty() || purchase.purchaseToken.isEmpty()
                ) {
                    return
                }

                appViewModel.doSubscribe(
                    purchase.products[0],
                    purchase.orderId,
                    purchase.purchaseToken
                )

                trackSubscriptionToAdjust(purchase)
            }
        }, this)

        val billingFlowDraftCallback: BillingFlowDraftCallback =
            object : BillingFlowDraftCallback {
                /**
                 * 检查通过，可对目标商品进行购买。
                 * 1.首次购买一次性内购商品。
                 * 2.首次购买订阅商品。
                 * 3.已拥有一个订阅商品，但不是目标商品：升级或者降级。
                 * 4.重复购买消耗性内购商品。
                 */
                override fun onReadyToBuy(billingFlowParams: BillingFlowParams) {
                    // 启动购买流程。
                    val responseCode = Billing.launchBillingFlow(
                        this@BillingActivity,
                        billingFlowParams
                    ).responseCode
                    if (responseCode != BillingClient.BillingResponseCode.OK) {
                        // 启动购买流程失败，根据错误码判断错误类型。
                    }
                }
            }

        binding.subBtnTry.setOnClickListener {
            Billing.draftBillingFlow(
                subId,
                this,
                billingFlowDraftCallback,
                forceLaunchBillingFlow = true
            )
        }
    }

    private fun trackSubscriptionToAdjust(purchase: Purchase) {
        val sku = purchase.products[0]
        var price = 0L
        Billing.getOriginalPrice(sku)?.let {
            price = it
        }
        val currency = Billing.getPriceCurrencyCode(sku)
        val orderId = purchase.orderId
        val signature = purchase.signature
        val purchaseToken = purchase.purchaseToken
        val subscription = AdjustPlayStoreSubscription(
            price,
            currency,
            sku,
            orderId,
            signature,
            purchaseToken
        )
        subscription.purchaseTime = purchase.purchaseTime
        Adjust.trackPlayStoreSubscription(subscription)
    }

    override fun onDestroy() {
        super.onDestroy()
        when {
            this::animatorSet.isInitialized -> {
                animatorSet.cancel()
            }
        }
    }

    override fun onBackPressed() {

    }

    companion object {
        const val KEY_VIP_TYPE = "KEY_VIP_TYPE"  //开启试用/付费来源
        const val KEY_SUBSCRIPTION_EVENTS_LOGGED = "key_subscription_events_logged"
    }
}